          PH.ARGS DRPT,AOD,AGD,HBRCHS,INCLNUL,BRCHS,OPT,SRV.CHRG,QUICK,STATS,VCURR,XCURR,LAST,SLCT.CNS,FITEM,EXTRA.DATA
** Version# 124.0001[1] - 08/11/2011 - 02:59pm - SMITJR - eclipse

*** Program: AR.PHR.AGING
*-------------------------------------------------------------------------*
*** This is the Phantom routine for the A/R Aging Report.
*** The main purpose of the A/R Aging report is to show how much money
*** the User's customers owe their company and how long the money has been
*** owed. It can also shows the date of the customer's last payment and the
*** amount last paid. The field prompts in the Driver let the User modify
*** the report according to the kind and extent of information desired.
*** NOTE:
*** If "Apply credits to oldest buckets when aging account" is flagged on
*** a customer's Credit Control Paramters, the report will display all
*** credits as applied to the oldest aging bucket with a balance.
*-------------------------------------------------------------------------*
*** DRPT       - Report Printing Defaults.                            [IN]
*** AOD        - As of Date                                           (IN)
***              > Only invoices dated up to and including the
***                As of Date will be included on the report.
*** AGD        - Aging As of Date -> Age data as of this date.        (IN)
*** HBRCHS     - Home Branches to include data for.                   (IN)
*** INCLNUL    - Flag for whether to include Null Home Branches       [IN]
***              > Since a home branch designation is optional for a
***                customer the Incl Blank Home Br prompt lets the User
***                include in the report all customers who do not have
***                a home branch assigned on the Accessible Branches
***                screen off of Custumer File Maintenance.
*** BRCHS      - Pricing Branches to include data for.                [IN]
*** OPT        - Summary/Detail/Unapplied View.                       (IN)
***              > Summary only shows aging totals (one line) for each
***                customer followed by grand totals for all customers.
***              > Detail shows all invoices and cash receipts for each
***                customer followed by the aging totals for that
***                customer. After all customers have been included,
***                grand totals for all customers are displayed.
***              > Unapplied provides a report in detail form that only
***                shows cash receipts that have not been applied to an
***                unpaid invoice. It does not include unapplied
***                credits.
*** SRV.CHR    - Variable that shows what to do with the invocies     (IN)
***              that are for unpaid Service Charges
***              > Include - Includes service charges
***              > Exclude - Excludes service charges
***              > Only    - Shows ONLY unpaid invoices that are
***                          for service charges
*** QUICK      - Flag set when no As of Date is entered by the user.  (IN)
***              > The As of Date and the Age As of Date will be set to
***                the current date.
*** STATS      - Invoice Status Code(s).                              (IN)
***              > This parameter restricts the report to include only
***                those invoices assigned a particular status code.
*** VCURR      - Customer Currency.                                   (IN)
***              > Will display data for only those customers who have a
***                designated primary currency (as defined in the Primary
***                Currency field on the Customer Maintenance / Customer
***                Pricing/Printing screen) different from the User's
***                base currency.
*** XCURR      - Report Currency.                                     (IN)
***              > Entire report will print in this Currency.
*** LAST       - Flag for whether to display the Amount and Date of   (IN)
***              the customer's last payment.
*** BT.CN      - BillTo Customers to report data for.                 (IN)
*** EXTRA.DATA - Extra data passed in through one parameter.          (IN)
***              EXTRA.DATA<1,1> - LEVEL:  Customer Level
***                Options Include: 'Bill-To' and 'Ship-To'.
***                When the Ship-To option is selected, Invoices will
***                be sorted, and subtotaled by ShipTo within each
***                Bill-To.
***              EXTRA.DATA<1,2> - RESPECT.BFWD: 'Respect Balance
***                Forward flags' option.
***                This option is only valid when the Report is NOT
***                run in Summary format, the 'Display Aging Invoices
***                From Balance Forward Perspective' Control Record
***                (AR.BF.VIEW) is set to 'Yes', AND the Customer we're
***                on is flagged for 'Balance Forward', rather than
***                Open Items, in Customer Maintenance.
***                > If set to 'Y'es, Invoice amounts that fall into any
***                  of the 30+, 60+, 90+, or 120+ age buckets will
***                  display as part of a 'Balance Fwd' TOTAL rather
***                  than in Invoice Detail. Future, Current, and
***                  Deposit amounts will still display in Invoice
***                  detail.
***                > If set to 'N'o, the AR.BF.VIEW Control Record and
***                  'Bal Fwd/Open Item' flag are ignored, and all
***                  Invoices are displayed in Detail.
***             EXTRA.DATA<1,3> - SORT.BY: Column to Sort by
***             EXTRA.DATA<1,4> - SRT.ORDER: Ascending or Descending Sort
***             EXTRA.DATA<1,5> - Customer Terms Code(s). Only
***                Customers with having these Terms Codes will be
***                included on the report.
***             EXTRA.DATA<1,6> - SLCT.CRD: Credit Manager selection
***             EXTRA.DATA<1,7> - Order Terms flag, if yes and terms
***                has been selected to appear on the report, LED(29)
***                will be checked first and used if not null.
***             EXTRA.DATA<1,8> - Activity Source, can be null.
***             EXTRA.DATA<1,9> - Activity Date, if not null we look
***                to see if there are trackers with comments after this
***                date, and filters against type (EXTRA.DATA<1,8>) as
***                well. Adds to the end of the report. This added
***                function doesn't interferre with ANY previous logic
***                in this report.
***             EXTRA.DATA<1,10> - Include zero balance customers. Used
***                to help keep rows aligned properly when downloaded
***                to Excel.
*-------------------------------------------------------------------------*
*** Common Variables Used: DRPT
*-------------------------------------------------------------------------*
          * Set report option (Detail or Summary)
          DETAIL = (OPT#'S')
          IF DETAIL THEN REPORT.TYPE = 'D' ELSE REPORT.TYPE = 'S'

          * Get the detail or summary column information for the report
          REPORT.V.COL.GET.DATA 'AR.AGING',DRPT<56>,COL.RECORD,REPORT.TYPE
          IF COL.RECORD = '' THEN
             ERR.MSG  = 'Missing report data for A/R Aging Report. '
             ERR.MSG := 'Contact you support representative'
             GOSUB NOTIFY.USER
             STOP
          END

          LEVEL         = EXTRA.DATA<1,1>         ;* Bill-To/Ship-To
          RESPECT.BFWD  = EXTRA.DATA<1,2>         ;* Balance Forward Flag
          SORT.BY       = EXTRA.DATA<1,3>         ;* Sort By Option
          SRT.ORDER     = EXTRA.DATA<1,4>         ;* Ascending/Descending
          TERMS         = RAISE(EXTRA.DATA<1,5>)  ;* Filter Terms
          SRV.CHRG.TYP  = SRV.CHRG[1,1]           ;* Service Charge Option
          SLCT.CRD      = RAISE(EXTRA.DATA<1,6>)  ;* Credit Manager List
          ACT.SRC       = EXTRA.DATA<1,8>         ;* Activity Source
          ACT.DT        = EXTRA.DATA<1,9>         ;* Activity Cut Date
          IZBC          = EXTRA.DATA<1,10>        ;* Incl Zero Bal CUS

          * Mask the parent level selection to bill-to customer.
          REAL.LEVEL = LEVEL
          IF LEVEL[1,1] = 'P' THEN
             LEVEL = 'Bill-To'
          END

          CURR.FLG = NO
          IF XCURR THEN
             READ BASEC FROM CTRLFILE,"BASE.CURRENCY" ELSE BASEC = ''
             IF XCURR # BASEC THEN CURR.FLG = YES
          END

          IF QUICK THEN
             ASOF = 'All Dates; Printed ':OCONV(DATE(),'D4/')
             AGDT = OCONV(DATE(),'D4/')
             AOD  = ''; AGD = DATE()
          END ELSE
             ASOF = OCONV(AOD,'D4/')
             AGDT = OCONV(AGD,'D4/')
          END

          HBRS   = HBRCHS<1,2>            ;* Home Branches to include
          HBRCHS = RAISE(HBRCHS<1,1>)     ;* Home Branch literal
          SBRS   = BRCHS<1,2>             ;* Sale Branches to include
          BRCHS  = RAISE(BRCHS<1,1>)      ;* Sale Branch literal
          BRS    = BRCHS

          * Change variables holders for customer, branch, levels
          TEMP.CN = '@@@'
          TEMP.BR = '@@@'

          CUSTOMER.TOTALS = ''
          BILLTO.TOTALS   = ''
          BRANCH.TOTALS   = ''
          GRAND.TOTALS    = ''

          CUSTOMER.OPEN   = ''
          BILLTO.OPEN     = ''
          BRANCH.OPEN     = ''
          GRAND.OPEN      = ''

          BT.COMMENTS.PRINTED = ''

          ERR.MSG     = ''
          RPT.VALS    = SORT.BY
          RPT.VALS<2> = SRT.ORDER
          RPT.VALS<3> = DETAIL

          * Create a Temp File to store our Report data in...
          AR.AGING.CREATE.FILE RPT.VALS,SORTFLNM,SORTFILE,SORT.VALS,ERR.MSG
          IF ERR.MSG THEN GOSUB NOTIFY.USER; STOP

          SORT.OPT = SORT.VALS<1>
          EXEC     = SORT.VALS<2>

          BALFWD = NO; FORWARD.BUCKETS = ''
          * Read in the value set in the 'Display Aging Invoices From
          * Balances Forward Perspective' Control Record...
          READ BALFWD.REC FROM CTRLFILE,'AR.BF.VIEW' ELSE BALFWD.REC = ''
*-------------------------------------------------------------------------*

          PH.STATUS 'Selecting....'
          GOSUB SEL.IDS
*-------------------------------------------------------------------------*
          * Turn our printer on and print the report...
          GOSUB SETHDR
          PRINTER.ON WDTH,TITLE,DOC.ID,HDR,RPT.DFLT=DRPT
          FILTER.PRINT "S",FITEM

          PH.STATUS 'Spooling .... '
          EXECUTE 'SSELECT ':SORTFLNM:' ':EXEC CAPTURING MSG
          READLIST TRANS.LIST ELSE TRANS.LIST = ''
          TOTAL.CT = DCOUNT(TRANS.LIST,AM); CT = 0
          MOREDATA = (TRANS.LIST#'')
          LOOP WHILE MOREDATA
             REMOVE TID FROM TRANS.LIST SETTING MOREDATA
             GOSUB PRINTONE; CT += 1
             * Update the process status
             IF MOD(CT,100) = 0 THEN
                PERC = (CT/TOTAL.CT)*100
                PH.STATUS 'Spooling .... ':CT:'/':TOTAL.CT:' (':PERC:'%)'
             END
          REPEAT

          * Print the last detail line and increment the totals
          IF DETAIL THEN
             GOSUB PRINT.DETAIL.TOTAL
          END

          * If we broke our data out by ShipTo Customer,
          * go print the last Bill-To Customer's Totals
          IF LEVEL[1,1] = 'S' THEN
             GOSUB PRINT.BILLTO.TOTALS
          END

          * If we broke our data out by branch (sale/home)
          * go print the last branchs totals
          IF (SORT.OPT = 9 OR SORT.OPT = 10) THEN
             GOSUB PRINT.BRANCH.TOTALS
          END

          * Go Print the Grand Totals
          GOSUB PRINT.GRAND.TOTALS

          * Turn our Printer off and clean up after ourselves
          PRINTER.OFF DOC.ID

          UT.TEMPFILE.DELETE SORTFLNM
          UT.PH.CLEANUP

          SEND.MESSAGE 'Phantom',USER.ID,TITLE:' is Complete'
          RETURN
*-------------------------------------------------------------------------*
SETHDR:   *** Set up the report heading which basically details all of
          *** the various print options used to print this report
          HDR.VARS     = DETAIL                      ;* Detail/Summary
          HDR.VARS<2>  = REAL.LEVEL                  ;* Bill-To/Ship-To
          HDR.VARS<3>  = ASOF                        ;* As of Date
          HDR.VARS<4>  = SRV.CHRG.TYP                ;* Service Charge Opt
          HDR.VARS<5>  = STATS                       ;* Invoice Statuses
          HDR.VARS<6>  = HBRS                        ;* Home Branches
          HDR.VARS<7>  = SBRS                        ;* Sale Branches
          HDR.VARS<8>  = SRT.ORDER:VM:SORT.BY        ;* Sort options
          HDR.VARS<9>  = ACT.DT:VM:ACT.SRC           ;* Activity comments
          HDR.VARS<10> = CURR.FLG:VM:VCURR:VM:XCURR  ;* Currencey Info
          HDR.VARS<11> = TERMS                       ;* Terms Codes
          HDR.VARS<12> = SLCT.CRD                    ;* Credit Managers
          HDR.VARS<13> = OPT                         ;* Detail/Summary/Unap
          HDR.VARS<14> = DRPT<33>
          AR.AGING.BUILD.HDR HDR,TITLE,WDTH,HDR.VARS,COL.RECORD
          RETURN
*-------------------------------------------------------------------------*
SEL.IDS:  *** Select and sort our records caching in a tempfile
          FLNMINFO       = CUSFILE              ;* Source file
          POST.SUBR      = 'AR.AGING.GET.DATA'  ;* Processing subroutine
          SELECT.INFO    = 1                    ;* Select mode
          IF SLCT.CNS THEN
             SAVEL.ID = 'AR.PHR.AGING.':PID$
             RAISE.CNS = RAISE(SLCT.CNS)
             WRITELIST RAISE.CNS ON SAVEL.ID
             SELECT.STMT = 'GET.LIST ':SAVEL.ID
          END ELSE SELECT.STMT = ''
          SELECT.INFO<2> = SELECT.STMT
          PROC.INFO      = 1                    ;* Thread# identifier
          PROC.INFO<2,1> = DRPT<61,2>           ;* Thread count
          PROC.INFO<2,2> = DRPT<61,3>           ;* Thread work load
          PROC.INFO<3,1> = DRPT<61,4>           ;* Allow regeneration
          PROC.INFO<3,2> = DRPT<61,5>           ;* # of retries
          PROC.INFO<4,1> = DRPT<53,1>           ;* Reporting Server

          SUBR.INFO      = SORTFLNM             ;* Tempfile to cache aging
          SUBR.INFO<2>   = SORT.OPT             ;* Sort by
          SUBR.INFO<3>   = COL.RECORD<1>        ;* Column data
          SUBR.INFO      = LOWER(SUBR.INFO)

          * Fork out selection/processing on multiple threads
          PHANTOM.THREAD FLNMINFO,POST.SUBR,SELECT.INFO,PROC.INFO,SUBR.INFO
          IF SLCT.CNS THEN
             DELETELIST SAVEL.ID
          END
          RETURN
*-------------------------------------------------------------------------*
PRINTONE: *** Print one Customer's data - All appropriate Invoices, along
          *** with the age bucket each balance is in, and then the
          *** Customer's Totals
          READ TREC FROM SORTFILE,TID ELSE TREC = ''
          BT.CN  = FIELD(TID,'~',2)   ;* Bill-To customer
          ST.CN  = FIELD(TID,'~',4)   ;* Ship-To customer
          AR.ID  = FIELD(TID,'~',6)   ;* AR record ID
          AGT    = TREC[AM,3,7]       ;* Aging buckets
          ANYBAL = ANY.NON.ZERO(AGT)  ;* Boolean if non-zero value in array
          IF IZBC AND NOT(ANYBAL) THEN ANYBAL = 1 ;*Incl Zero Bal CUS
          BAL    = TREC<12,1>         ;* Invoice balance
          DINFO  = RAISE(TREC<12,2>)  ;* Invoice aging pointers
          HB     = TREC<13>           ;* Home branch
          SBR    = TREC<14>           ;* Sale branch
          SALES.TAX = TREC<16>        ;* Sales Tax

          * Set the customer based on the level we are printing at
          IF LEVEL[1,1] = 'S' THEN CN = ST.CN ELSE CN = BT.CN

          * Set the branch to break on based on the sort option
          BEGIN CASE
          CASE SORT.OPT = 9;  SORT.BR = HB
          CASE SORT.OPT = 10; SORT.BR = SBR
          CASE OTHERWISE;     SORT.BR = ''
          END CASE

          FIRST.CUSTOMER     = (TEMP.CN = '@@@')
          CUSTOMER.CHANGE    = (TEMP.CN # CN) AND (TEMP.CN # '@@@')
          BRANCH.CHANGE      = (TEMP.BR # SORT.BR)
          BT.CUSTOMER.CHANGE = (LAST.BT # BT.CN)
          IF (FIRST.CUSTOMER) THEN LAST.BT = BT.CN

          * If this isn't the first customer and we are in detail mode
          * then print a summary total line for this customer. In
          * summary mode we always print the equivilant of this for
          * every line.
          IF DETAIL AND CUSTOMER.CHANGE THEN
             GOSUB PRINT.DETAIL.TOTAL
          END

          * If we're breaking our data out by ShipTo Customer and
          * we're on a new BillTo Customer, print the Totals for
          * the last BillTo...
          IF LEVEL[1,1] = 'S' AND BT.CUSTOMER.CHANGE AND CUSTOMER.CHANGE THEN
             GOSUB PRINT.BILLTO.TOTALS
             LAST.BT = BT.CN
          END

          * If the branch (home/sale) changes then print out
          * the totals for the last branch
          IF BRANCH.CHANGE THEN
             IF (TEMP.BR # '@@@') THEN
                GOSUB PRINT.BRANCH.TOTALS
             END
             TEMP.BR = SORT.BR
          END

          * If the customer changes load next customers info. This will
          * be the customers name, balance forward and last payment info
          IF (CUSTOMER.CHANGE OR FIRST.CUSTOMER) THEN GOSUB LOAD.CUSTOMER

          BEGIN CASE
          CASE DETAIL AND (BAL OR IZBC)
             IF (CUSTOMER.CHANGE OR FIRST.CUSTOMER) THEN
                * If we just changed customers then print
                * the header for the upcoming aging detail
                GOSUB PRINT.DETAIL.HDR
             END
             GOSUB PRINT.DETAIL.LINE
          CASE NOT(DETAIL) AND (ANYBAL OR LEVEL[1,1] = 'S')
             * Print the summary totals. The header and detail
             * are all one line in this mode
             GOSUB PRINT.SUMMARY.LINE
          CASE OTHERWISE; NULL
          END CASE
          RETURN
*-------------------------------------------------------------------------*
LOAD.CUSTOMER:*** Load info for the next customer we are processing

          TEMP.CN = CN
          READV CUS.NAME FROM CUSFILE,TEMP.CN,1 ELSE CUS.NAME = ''

          * Determine if the last payment information is even on the report
          * so we can avoid the overhead of calculating it if it is not.
          NEED.LAST = NO
          REPCOLS   = COL.RECORD<1>
          LOCATE '9' IN REPCOLS<1> SETTING VPOS THEN NEED.LAST=YES ELSE
             LOCATE '10' IN REPCOLS<1> SETTING VPOS THEN NEED.LAST=YES ELSE
                NULL
             END
          END

          IF NEED.LAST THEN
             * If we're on the first record for the current customer, get
             * the last Payment information and the As of Date
             AR.LASTTRANS CN,AOD,'C',LPDATE,LPREF,LPAMT,1
             IF NOT(LPDATE) THEN LPAMT = ''
             * Convert our Currency if necessary...
             IF CURR.FLG AND LPDATE THEN
                XCURR.RATE.GET XRATE,XCURR,LPDATE
                XRATE = OCONV(XRATE,'MR4')
                IF XRATE + 0 = 0 THEN XRATE = 1
                CONV.CURR.AMT XRATE,LPAMT,NEW.AMT,AM
                LPAMT = NEW.AMT
             END
          END ELSE
             LPDATE = ''; LPAMT = ''
          END

          * Check the Balance Foward/Open Items flag
          * set for this Customer...
          IF RESPECT.BFWD AND BALFWD.REC AND DETAIL THEN
             READV BFWD.FLAG FROM CUSFILE,CN,63 ELSE BFWD.FLAG = ''
             * 'B' = Balance Forward, 'O' = Open Items...
             IF BFWD.FLAG # 'B' THEN BALFWD = NO ELSE BALFWD = YES
          END

          CUSTOMER.LINES.PRINTED = 0
          RETURN
*-------------------------------------------------------------------------*
PRINT.DETAIL.HDR:* Print Data columns for the Detail/Unapplied View...
          PCOLS     = ''
          PCOLS<1>  =  '........................'    ;* Future
          PCOLS<2>  =  '........................'    ;* Current
          PCOLS<3>  =  '........................'    ;* 31-60
          PCOLS<4>  =  '........................'    ;* 61-90
          PCOLS<5>  =  '........................'    ;* 91-120
          PCOLS<6>  =  '........................'    ;* Over 120
          PCOLS<7>  =  '........................'    ;* Deposits
          PCOLS<8>  =  '........................'    ;* Balance
          PCOLS<9>  =  OCONV(LPDATE,'D4/')           ;* Last Pmt Dt
          PCOLS<10> =  OCONV(-LPAMT,'MR2')           ;* Last Pmt Amt
          PCOLS<11> =  '........................'    ;* Sales Tax
          ST.INDEX = TRANS('ENTITY',ST.CN,9,'X')
          READV CUS.PHONE FROM CUSFILE,CN,17 ELSE CUS.PHONE = ''
          PR.STR    = CN                             "L#6" :' '
          PR.STR   := ST.INDEX                       "L#36":' '
          PR.STR   := 'Phone : ':CUS.PHONE<1,1>
          REPORT.LAYOUT.V.PRINT.STR PCOLS,'',COL.RECORD,'',PR.STR
          PRINT PR.STR
          RETURN
*-------------------------------------------------------------------------*
PRINT.DETAIL.LINE:*** Print invoice total for a customer in detail mode
          IF BALFWD THEN
             GOSUB CHECK.BALFWD.LINE
             IF PUSH.BAL THEN
                FORWARD.BUCKETS = ADDS(FORWARD.BUCKETS,TREC[AM,3,7])
             END
          END ELSE PUSH.BAL = NO

          IF NOT(PUSH.BAL) THEN
             RPT.VALS      = CURR.FLG
             RPT.VALS<1,2> = XCURR
             AR.AGING.PRINT.DETAIL TID,TREC,RPT.VALS,COL.RECORD
          END

          CUSTOMER.TOTALS = ADDS(CUSTOMER.TOTALS,TREC[AM,3,7])
          CUSTOMER.TOTALS<8>  += BAL
          CUSTOMER.TOTALS<11> += SALES.TAX

          CUSTOMER.LINES.PRINTED += 1
          RETURN
*-------------------------------------------------------------------------*
PRINT.BALFWD.HDR:
          * If we should be printing our 30+, 60+, 90+ and 120+
          * bucket TOTALS as 'Balance Forward' rather than in detail...
          PSTR   = ''
          PR.STR = SPACE(53):'Balance Fwd':SPACE(35)
          AR.AGING.PRINT.TOTALS COL.RECORD,FORWARD.BUCKETS,PR.STR,'',PSTR
          RETURN
*-------------------------------------------------------------------------*
CHECK.BALFWD.LINE:*** If we are printing Aged Bucket Totals as
          *** 'Balance Forward' make sure this invoice falls into 30-120+
          PUSH.BAL  = NO
          BUCKET.CT = DCOUNT(DINFO,VM)
          FOR BCKT  = 1 TO BUCKET.CT
             PART.CRED.AG = DINFO<1,BCKT,1>
             * If the current Invoice we're on is from one of
             * our 30+, 60+, 90+ or 120+ age buckets...
             IF PART.CRED.AG >= 3 AND PART.CRED.AG <= 6 THEN
                PUSH.BAL = YES; EXIT
             END
          NEXT BCKT
          RETURN
*-------------------------------------------------------------------------*
PRINT.DETAIL.TOTAL:*** Print the totals for the customer which proceeds
          *** each of the line item detail invoices
          IF BALFWD THEN
             * Print balance forward totals
             GOSUB PRINT.BALFWD.HDR
          END

          * Get open amount total
          OPEN.ORDER.AMT OPEN.AMT,TEMP.CN:AM:TEMP.CN
          CUSTOMER.TOTALS<17> = OPEN.AMT

          BRANCH.TOTALS = ADDS(BRANCH.TOTALS,CUSTOMER.TOTALS)
          GRAND.TOTALS  = ADDS(GRAND.TOTALS,CUSTOMER.TOTALS)

          PSTR   = ''
          PR.STR = SPACE(15):"Total for Customer ":ST.INDEX "L#36"
          AR.AGING.PRINT.TOTALS COL.RECORD,CUSTOMER.TOTALS,PR.STR,'-',PSTR

          * Add to our BillTo Totals
          BILLTO.TOTALS = ADDS(BILLTO.TOTALS,CUSTOMER.TOTALS)

          CUSTOMER.TOTALS = ''; CUSTOMER.OPEN = ''

          * TEMP.CN is the customer ID we are currently working with
          IF ACT.DT THEN
             COM.CNS = TEMP.CN
             GOSUB ACT.CMTS
          END

          RETURN
*-------------------------------------------------------------------------*
PRINT.SUMMARY.LINE: *** Print the totals for the customer in summary mode
          BRANCH.TOTALS = ADDS(BRANCH.TOTALS,TREC[AM,3,7])
          GRAND.TOTALS  = ADDS(GRAND.TOTALS,TREC[AM,3,7])
          BUCKET.TOTALS = SUMMATION(TREC[AM,3,7])

          GRAND.TOTALS<8>  += BUCKET.TOTALS
          BRANCH.TOTALS<8> += BUCKET.TOTALS

          TREC<10> = LPDATE  ;* Last Pmt Dt
          TREC<11> = LPAMT   ;* Last Pmt Amt

          RPT.VALS      = CURR.FLG
          RPT.VALS<1,2> = XCURR
          RPT.VALS<2>   = LEVEL
          RPT.VALS<3>   = SORT.OPT
          RPT.VALS<4>   = AOD
          AR.AGING.PRINT.SUMMARY TID,TREC,RPT.VALS,COL.RECORD,OPEN.AMT

          * Add to our BillTo Totals
          BILLTO.TOTALS     = ADDS(BILLTO.TOTALS,TREC[AM,3,7])
          BILLTO.TOTALS<8> += BUCKET.TOTALS

          GRAND.OPEN  += OPEN.AMT; BRANCH.OPEN += OPEN.AMT
          BILLTO.OPEN += OPEN.AMT

          * CN is the customer ID we are currently working with
          IF ACT.DT THEN
             COM.CNS = CN
             GOSUB ACT.CMTS
          END
          RETURN
*-------------------------------------------------------------------------*
PRINT.BILLTO.TOTALS:*** Print the Bill-To Customer Totals
          READV BTNAME FROM CUSFILE,LAST.BT,1 ELSE BTNAME = ''
          BTNAME = TRIM(BTNAME)

          IF DETAIL THEN
             PR.STR  = SPACE(5):'Totals for Bill-To: '
             PST.STR = ''
          END ELSE
             PR.STR   = 'Totals for BT: '
             PST.STR = BILLTO.OPEN
          END

          PR.STR := '&':LAST.BT:' ':BTNAME
          PR.STR.LENGTH = LEN(PR.STR)

          IF NOT(DETAIL) THEN
             PST.STR = BRANCH.OPEN "R26,#15"
          END ELSE PST.STR = ''

          AR.AGING.PRINT.TOTALS COL.RECORD,BILLTO.TOTALS,PR.STR,'-',PST.STR
          BILLTO.TOTALS = ''; BILLTO.OPEN = ''

          * LAST.BT is the customer ID we are currently working with
          * No print comments if they already happend at shipto level
          IF ACT.DT AND LAST.BT # BT.COMMENTS.PRINTED THEN
             COM.CNS = LAST.BT
             GOSUB ACT.CMTS
          END
          RETURN
*-------------------------------------------------------------------------*
PRINT.GRAND.TOTALS:*** Print the grand total for the entire report

          PR.STR = 'Grand Totals'

          * Insert the grand total for Open orders. We use position 17
          * because that corresponds to the position of 'Open Orders'
          * in COL.RECORD<2>
          GRAND.TOTALS<17> = GRAND.OPEN

          IF USER.ID = 'ECLIPSE' THEN
             * For Eclipse users store the total AR balance versus G/L
             GL.GET.AMT GL.AUTO.AR,'',BRS,AOD,BALANCE
             CTRL.REC    = 'AR: ':GRAND.TOTALS<8>
             CTRL.REC<2> = 'GL: ':BALANCE
          END
          AR.AGING.PRINT.TOTALS COL.RECORD,GRAND.TOTALS,PR.STR,'='
          RETURN
*-------------------------------------------------------------------------*
PRINT.BRANCH.TOTALS:*** Print the total for the entire branch (home/sale)
          IF DETAIL THEN
             PR.STR  = SPACE(48-LEN(SORT.BY)):'Totals for ':SORT.BY:' '
             PR.STR := TEMP.BR "L#4"
             PR.STR := ':':SPACE(5)
             PST.STR = PR.STR
          END ELSE
             PR.STR  = SPACE(20-LEN(SORT.BY)):'Totals for ':SORT.BY:' '
             PR.STR := TEMP.BR "L#4"
             PR.STR := ':':SPACE(5)
             PST.STR = BRANCH.OPEN "R26,#15"
          END

          AR.AGING.PRINT.TOTALS COL.RECORD,BRANCH.TOTALS,PR.STR,'=',PST.STR
          BRANCH.TOTALS = ''; BRANCH.OPEN = ''
          RETURN
*-------------------------------------------------------------------------*
ACT.CMTS: *** Build comment array (CMT.ARRAY)

          IF LEVEL[1,1] = 'B' THEN
             * Get all ShipTo customer's comments as well as the BillTo
             READV ST.CNS FROM CUSFILE,COM.CNS,14 ELSE ST.CNS = ''
             IF ST.CNS # '' THEN
                COM.CNS<-1> = RAISE(ST.CNS)
                UNIQUEA COM.CNS,NEW.CNS
                COM.CNS = NEW.CNS
             END
          END ELSE
             * Only print Bill-To customer once in sort by Ship-To
             IF COM.CNS = BT.COMMENTS.PRINTED THEN
                RETURN
             END
          END

          * Print Customer Comments
          CUS.PRINT.COMMENTS COM.CNS,ACT.DT,ACT.SRC

          * Marker to indicate Bill-To comments have already printed
          IF LEVEL[1,1] = 'S' AND LAST.BT = COM.CNS THEN
             BT.COMMENTS.PRINTED = LAST.BT
          END
          RETURN
*-------------------------------------------------------------------------*
NOTIFY.USER:*** Send user notification
          SEND.MESSAGE 'Phantom',USER.ID,ERR.MSG
          RETURN
*-------------------------------------------------------------------------*
!MHOOTEN~11/30/04~13:10

!SMITJR~08/11/11~14:59
